//-
// ==========================================================================
// Copyright (C) 1995 - 2006 Autodesk, Inc. and/or its licensors.  All 
// rights reserved.
//
// The coded instructions, statements, computer programs, and/or related 
// material (collectively the "Data") in these files contain unpublished 
// information proprietary to Autodesk, Inc. ("Autodesk") and/or its 
// licensors, which is protected by U.S. and Canadian federal copyright 
// law and by international treaties.
//
// The Data is provided for use exclusively by You. You have the right 
// to use, modify, and incorporate this Data into other products for 
// purposes authorized by the Autodesk software license agreement, 
// without fee.
//
// The copyright notices in the Software and this entire statement, 
// including the above license grant, this restriction and the 
// following disclaimer, must be included in all copies of the 
// Software, in whole or in part, and all derivative works of 
// the Software, unless such copies or derivative works are solely 
// in the form of machine-executable object code generated by a 
// source language processor.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND. 
// AUTODESK DOES NOT MAKE AND HEREBY DISCLAIMS ANY EXPRESS OR IMPLIED 
// WARRANTIES INCLUDING, BUT NOT LIMITED TO, THE WARRANTIES OF 
// NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR 
// PURPOSE, OR ARISING FROM A COURSE OF DEALING, USAGE, OR 
// TRADE PRACTICE. IN NO EVENT WILL AUTODESK AND/OR ITS LICENSORS 
// BE LIABLE FOR ANY LOST REVENUES, DATA, OR PROFITS, OR SPECIAL, 
// DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES, EVEN IF AUTODESK 
// AND/OR ITS LICENSORS HAS BEEN ADVISED OF THE POSSIBILITY 
// OR PROBABILITY OF SUCH DAMAGES.
//
// ==========================================================================
//+

////////////////////////////////////////////////////////////////////////
//
// node_info.cc
//
// This plugin prints out type and connected plug information for
// the selected dependency nodes.
//
////////////////////////////////////////////////////////////////////////

#include <maya/MIOStream.h>
#include <maya/MFnPlugin.h>
#include <maya/MString.h>
#include <maya/MArgList.h>

#include <maya/MPxCommand.h>
#include <maya/MSyntax.h>
#include <maya/MArgDatabase.h>

#include <maya/MGlobal.h>
#include <maya/MDagPath.h>
#include <maya/MItSelectionList.h>
#include <maya/MSelectionList.h>

#include <maya/MFnDependencyNode.h>
#include <maya/MPlugArray.h>
#include <maya/MPlug.h>

#define kQuietFlag		"-q"
#define kQuietFlagLong	"-quiet"

///////////////////////////////////////////////////
//
// Command class declaration
//
///////////////////////////////////////////////////
class nodeInfo : public MPxCommand
{
public:
					nodeInfo();
	virtual			~nodeInfo(); 

	MStatus			doIt( const MArgList& args );

	static MSyntax	newSyntax();
	static void*	creator();

private:
	void			printType( const MObject& node, const MString& prefix );
	MStatus			parseArgs( const MArgList& args );
	bool			quiet;
};



///////////////////////////////////////////////////
//
// Command class implementation
//
///////////////////////////////////////////////////

nodeInfo::nodeInfo()
	: quiet (false)
{}

nodeInfo::~nodeInfo() {}

void* nodeInfo::creator()
{
	return new nodeInfo;
}

MSyntax nodeInfo::newSyntax()
{
	 MSyntax syntax;
	 syntax.addFlag(kQuietFlag, kQuietFlagLong);
	 return syntax;
}

MStatus nodeInfo::parseArgs( const MArgList& args )
{
	MStatus			stat;
	MArgDatabase	argData(syntax(), args);

	if (argData.isFlagSet(kQuietFlag))
		quiet = true;

	return stat;
}

MStatus nodeInfo::doIt( const MArgList& args )
//
// Description
//     This method performs the action of the command.
//
//     This method iterates over all selected items and
//     prints out connected plug and dependency node type
//     information.
//
{
	MStatus stat;			// Status code
	MObject dependNode;		// Selected dependency node

	stat = parseArgs ( args );
	if ( !stat )
		return stat;

	// Create a selection list iterator
	//
	MSelectionList slist;
	MGlobal::getActiveSelectionList( slist );
	MItSelectionList iter( slist, MFn::kInvalid,&stat );


	// Iterate over all selected dependency nodes
	//
	for ( ; !iter.isDone(); iter.next() ) 
	{
		// Get the selected dependency node
		//
		stat = iter.getDependNode( dependNode );
		if ( !stat ) {
			stat.perror("getDependNode");
			continue;
		}

		// Create a function set for the dependency node
		//
		MFnDependencyNode fnDependNode( dependNode );

		// Check the type of the dependency node
		//
		MString nodeName = fnDependNode.name();
		nodeName += ": ";
		printType( dependNode, nodeName );

		// Get all connected plugs to this node
		//
		MPlugArray connectedPlugs;
		stat = fnDependNode.getConnections( connectedPlugs );

		int numberOfPlugs = connectedPlugs.length();
		if ( !quiet )
			cerr << "  Found: " << numberOfPlugs << " connections" << endl;

		// Print out the dependency node name and attributes
		// for each plug
		//
		for ( int i=0; i<numberOfPlugs; i++ ) 
		{
			MPlug plug = connectedPlugs[i];
			MString pinfo = plug.info();
			if ( !quiet )
				cerr << "  Plug info: " << pinfo << endl;

			// Now get the plugs that this plug is the
			// destination of and print the node type.
			//
			MPlugArray array;
			plug.connectedTo( array, true, false );

			for ( unsigned int j=0; j<array.length(); j++ )
			{
				MObject mnode = array[j].node();
				MString msg( "    This plug is a dest of a " );
				printType( mnode, msg );
			}
		}
	}
	return MS::kSuccess;
}

void nodeInfo::printType( const MObject& node, const MString& prefix )
//
// Description
//     This method prints the type of the given node.
//     prefix is a string that gets printed before the type name.
//
{
	if ( !quiet)
		cerr << prefix << node.apiTypeStr() << endl;

}



/////////////////////////////////////////////////////////////////
//
// The following routines are used to register/unregister
// the command we are creating within Maya
//
/////////////////////////////////////////////////////////////////
MStatus initializePlugin( MObject obj )
{
	MStatus   status;
	MFnPlugin plugin( obj, PLUGIN_COMPANY, "3.0", "Any");

	status = plugin.registerCommand( "nodeInfo",
									  nodeInfo::creator,
									  nodeInfo::newSyntax);
	if (!status) {
		status.perror("registerCommand");
		return status;
	}

	return status;
}

MStatus uninitializePlugin( MObject obj)
{
	MStatus	  status;
	MFnPlugin plugin( obj );

	status = plugin.deregisterCommand( "nodeInfo" );
	if (!status) {
		status.perror("deregisterCommand");
		return status;
	}

	return status;
}
